home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / Fl_Double_Window.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-01-07  |  5.4 KB  |  197 lines

  1. //
  2. // "$Id: Fl_Double_Window.cxx,v 1.12 1999/01/07 19:17:19 mike Exp $"
  3. //
  4. // Double-buffered window code for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. #include <config.h>
  27. #include <FL/Fl.H>
  28. #include <FL/Fl_Double_Window.H>
  29. #include <FL/x.H>
  30. #include <FL/fl_draw.H>
  31.  
  32. // On systems that support double buffering "naturally" the base
  33. // Fl_Window class will probably do double-buffer and this subclass
  34. // does nothing.
  35.  
  36. #if USE_XDBE
  37.  
  38. #include <X11/extensions/Xdbe.h>
  39.  
  40. static int use_xdbe;
  41.  
  42. static int can_xdbe() {
  43.   static int tried;
  44.   if (!tried) {
  45.     tried = 1;
  46.     int event_base, error_base;
  47.     if (!XdbeQueryExtension(fl_display, &event_base, &error_base)) return 0;
  48.     Drawable root = RootWindow(fl_display,fl_screen);
  49.     int numscreens = 1;
  50.     XdbeScreenVisualInfo *a = XdbeGetVisualInfo(fl_display,&root,&numscreens);
  51.     if (!a) return 0;
  52.     for (int j = 0; j < a->count; j++)
  53.       if (a->visinfo[j].visual == fl_visual->visualid
  54.       /*&& a->visinfo[j].perflevel > 0*/) {use_xdbe = 1; break;}
  55.     XdbeFreeVisualInfo(a);
  56.   }
  57.   return use_xdbe;
  58. }
  59. #endif
  60.  
  61. void Fl_Double_Window::show() {
  62. #ifndef WIN32
  63.   if (!shown()) { // don't set the background pixel
  64.     fl_open_display();
  65.     Fl_X::make_xid(this);
  66.     return;
  67.   }
  68. #endif
  69.   Fl_Window::show();
  70. }
  71.  
  72. #ifdef WIN32
  73.  
  74. // Code used to switch output to an off-screen window.  See macros in
  75. // win32.H which save the old state in local variables.
  76.  
  77. HDC fl_makeDC(HBITMAP bitmap) {
  78.   HDC new_gc = CreateCompatibleDC(fl_gc);
  79.   SetTextAlign(new_gc, TA_BASELINE|TA_LEFT);
  80.   SetBkMode(new_gc, TRANSPARENT);
  81. #if USE_COLORMAP
  82.   if (fl_palette) SelectPalette(new_gc, fl_palette, FALSE);
  83. #endif
  84.   SelectObject(new_gc, bitmap);
  85.   return new_gc;
  86. }
  87.  
  88. void fl_copy_offscreen(int x,int y,int w,int h,HBITMAP bitmap,int srcx,int srcy) {
  89.   HDC new_gc = CreateCompatibleDC(fl_gc);
  90.   SelectObject(new_gc, bitmap);
  91.   BitBlt(fl_gc, x, y, w, h, new_gc, srcx, srcy, SRCCOPY);
  92.   DeleteDC(new_gc);
  93. }
  94.  
  95. extern void fl_restore_clip();
  96.  
  97. #endif
  98.  
  99. // Fl_Overlay_Window relies on flush(1) copying the back buffer to the
  100. // front everywhere, even if damage() == 0, thus erasing the overlay,
  101. // and leaving the clip region set to the entire window.
  102.  
  103. void Fl_Double_Window::flush() {flush(0);}
  104.  
  105. void Fl_Double_Window::flush(int eraseoverlay) {
  106.   make_current(); // make sure fl_gc is non-zero
  107.   Fl_X *i = Fl_X::i(this);
  108.   if (!i->other_xid) {
  109. #if USE_XDBE
  110.     if (can_xdbe()) i->other_xid =
  111.       XdbeAllocateBackBufferName(fl_display, fl_xid(this), XdbeUndefined);
  112.     else
  113. #endif
  114.       i->other_xid = fl_create_offscreen(w(), h());
  115.     clear_damage(FL_DAMAGE_ALL);
  116.   }
  117. #if USE_XDBE
  118.   if (use_xdbe) {
  119.     // if this is true, copy rather than swap so back buffer is preserved:
  120.     int copy = (i->region || eraseoverlay);
  121.     if (i->backbuffer_bad) { // make sure we do a complete redraw...
  122.       if (i->region) {XDestroyRegion(i->region); i->region = 0;}
  123.       clear_damage(FL_DAMAGE_ALL);
  124.     }
  125.     if (damage()) {
  126.       fl_clip_region(i->region); i->region = 0;
  127.       fl_window = i->other_xid;
  128.       draw();
  129.       fl_window = i->xid;
  130.     }
  131.     if (!copy) {
  132.       XdbeSwapInfo s;
  133.       s.swap_window = fl_xid(this);
  134.       s.swap_action = XdbeUndefined;
  135.       XdbeSwapBuffers(fl_display, &s, 1);
  136.       i->backbuffer_bad = 1;
  137.       return;
  138.     }
  139.     // otherwise just use normal copy from back to front:
  140.     i->backbuffer_bad = 0; // which won't destroy the back buffer...
  141.   } else
  142. #endif
  143.   if (damage() & ~FL_DAMAGE_EXPOSE) {
  144.     fl_clip_region(i->region); i->region = 0;
  145. #ifdef WIN32
  146.     HDC _sgc = fl_gc;
  147.     fl_gc = fl_makeDC(i->other_xid);
  148.     fl_restore_clip(); // duplicate region into new gc
  149.     draw();
  150.     DeleteDC(fl_gc);
  151.     fl_gc = _sgc;
  152. #else // X:
  153.     fl_window = i->other_xid;
  154.     draw();
  155.     fl_window = i->xid;
  156. #endif
  157.   }
  158.   if (eraseoverlay) fl_clip_region(0);
  159.   // on Irix (at least) it is faster to reduce the area copied to
  160.   // the current clip region:
  161.   int X,Y,W,H; fl_clip_box(0,0,w(),h(),X,Y,W,H);
  162.   fl_copy_offscreen(X, Y, W, H, i->other_xid, X, Y);
  163. }
  164.  
  165. void Fl_Double_Window::resize(int X,int Y,int W,int H) {
  166.   int ow = w();
  167.   int oh = h();
  168.   Fl_Window::resize(X,Y,W,H);
  169. #if USE_XDBE
  170.   if (use_xdbe) return;
  171. #endif
  172.   Fl_X* i = Fl_X::i(this);
  173.   if (i && i->other_xid && (ow != w() || oh != h())) {
  174.     fl_delete_offscreen(i->other_xid);
  175.     i->other_xid = 0;
  176.   }
  177. }
  178.  
  179. void Fl_Double_Window::hide() {
  180.   Fl_X* i = Fl_X::i(this);
  181.   if (i && i->other_xid) {
  182. #if USE_XDBE
  183.     if (!use_xdbe)
  184. #endif
  185.       fl_delete_offscreen(i->other_xid);
  186.   }
  187.   Fl_Window::hide();
  188. }
  189.  
  190. Fl_Double_Window::~Fl_Double_Window() {
  191.   hide();
  192. }
  193.  
  194. //
  195. // End of "$Id: Fl_Double_Window.cxx,v 1.12 1999/01/07 19:17:19 mike Exp $".
  196. //
  197.